<?php


class Document {
	
	/**
	 * convert Document to html
	 */
	 
	public function DocumentToHTML() {
	
		$File = 'D:\\documents\\documents\\blog\\OOXML Wiki.docx';
		$Word = new COM('Word.Application');
		$Paragraphs = array();
		$Word->Documents->Open($File);
		$Document = $Word->ActiveDocument;
		$ParagraphCount = $Document->Paragraphs->Count();
		for ($i=1; $i<$ParagraphCount+1; $i++) {
			$Paragraph = $Document->Paragraphs->Item($i);
			// echo $Paragraph->Style."\n";
			// echo $Paragraph->Range->XML."\n";
			$XML = $Paragraph->Range->XML;
			// $this->XMLToHTML($XML);
			// echo $this->ParagraphsToHTML($XML)."\n";
			$Paragraphs[] = $this->ParagraphsToHTML($XML);
		}
		$Document->Close();
		$Word->Quit();
		echo implode('', $Paragraphs);
	}
	
	/**
	 * convert Paragraphs to html
	 */
	 
	public function ParagraphsToHTML($XML) {
		// get paragraph
		$Paragraphs = array();
		if (preg_match_all("/<w:p [^>]+>(.+)<\/w:p>/", $XML, $Match)) {
			// print_r($Match);
			foreach ($Match[1] as $Paragraph) {
				$Paragraphs[] = $this->ParagraphToHTML($Paragraph);
			}
		}
		return implode('',$Paragraphs);
	}
	
	/**
	 * convert Paragraph to html
	 */
	 
	public function ParagraphToHTML($Paragraph) {
		
		// convert style into html tags
		$Styles = array(
			'h1' => 'Title'
			);
			
		// default paragraph style
		$Style = 'p';
		
		// get paragraph style
		if (preg_match("/<w:pStyle w:val=\"([^\"]+)\"\/>/", $Paragraph, $Match)) {
			// print_r($Match);
			if (in_array($Match[1], $Styles)) {
				$StyleKeys = array_flip($Styles);
				$Style = $StyleKeys[$Match[1]];
			}
		}
	
		$Ranges = array();
		// remove paragraph property
		// echo $Paragraph."\n";
		$Paragraph = preg_replace("/<w:pPr>.+<\/w:pPr>/", '', $Paragraph);
		// echo $Paragraph."\n";
		// split into ranges
		if (preg_match_all("/<w:r[^>]*>(.+?)<\/w:r>/", $Paragraph, $Match)) {
			// print_r($Match);
			foreach ($Match[1] as $Range) {
				$Ranges[] = $this->RangeToHTML($Range);
			}
		}
		
		return '<'.$Style.'>'.implode('',$Ranges).'</'.$Style.'>';
	}
	
	/**
	 * convert Range to html
	 */
	
	public function RangeToHTML($Range) {
		
		// remove range and range property tags
		$Range = preg_replace("/<\/?w:r[^>]*>/", '', $Range);
		// remove text tags
		$Range = preg_replace("/<\/?w:t>/", '', $Range);
		// replace "w" namespace
		$Range = preg_replace("/<(\/)?w:([^>]+)(\/)?>/", '<\\1\\2\\3>', $Range);
		// language
		$Range = preg_replace("/<lang w:val=\"([^\"]+)\"/", '<span lang="\\1"', $Range); 		
		// replace complete /> tags
		if (preg_match_all("/<([^\/]+)\/>/", $Range, $Match)) {
			// print_r($Match);
			$HTMLTags = array_reverse($Match[1]);
			foreach ($HTMLTags as $HTMLTag) {
				$Range .= '</'.$HTMLTag.'>';
			}
		}
		$Range = preg_replace("/<([^\/]+)\/>/", '<\\1>', $Range);
		// remove property after closing tag
		$Range = preg_replace("/<\/([^\s]+)([^>]+)+>/", '</\\1>', $Range);
		
		return $Range;
	}	
}